package com.stu.covid.business.utils;


import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 时间操作工具类
 */
@Slf4j
public class DateUtils implements Serializable {
    private Calendar cal = Calendar.getInstance();

    public final static String FORMAT = "yyyy/MM/dd HH:mm:ss";

    public final static String FORMAT2 = "yyyy-MM-dd HH:mm:ss";

    public final static String FORMAT3 = "yyyy-MM-dd";

    private static SimpleDateFormat FORMAT_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");


    /**
     * 获取当前时间
     *
     * @return
     */
    public static Date getNowDate() {
        return new Date(System.currentTimeMillis());
    }

    /**
     * 获取时分秒
     *
     * @return
     */
    public static String getHMS(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        return format.format(date);
    }

    public static String formatDate(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(FORMAT);
        return format.format(date);
    }

    public static String formatDate2(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(FORMAT2);
        return format.format(date);
    }

    /**
     * 格式化成 yyyy-MM-dd HH:mm:ss
     *
     * @addPerson : hzb 2018-3-14
     */

    public static String formatDate(long date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT);
        String format = simpleDateFormat.format(date);
        return format;
    }

    /**
     * 格式化成 yyyy-MM-dd HH:mm:ss
     *
     * @addPerson : hzb 2018-3-14
     */

    public static String formatDate2(long date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(FORMAT2);
        String format = simpleDateFormat.format(date);
        return format;
    }

    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String format = simpleDateFormat.format(date);
        return format;
    }

    public static Date DateformatDate(Date date, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String format = simpleDateFormat.format(date);
        return DateUtils.strToDate(format, pattern);
    }

    /**
     * long 直接转换成date 类型
     *
     * @param date
     * @return 时间类型
     * @addPerson : hzb 2018-3-14
     */

    public Date longToDate(long date) {
        // 预防出现数据 串号的情况
        // cal= null;
        // 添加时间毫秒值进去
        cal.setTimeInMillis(date);
        // 获取时间类型
        return cal.getTime();
    }

    /**
     * 将时间格式字符串转换为时间
     *
     * @param strDate
     * @return
     */
    public static Date strToDate(String strDate, String pattern) {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        if (strDate.contains("-") && strDate.contains(":")) {
            pattern = FORMAT2;
        } else if (strDate.contains("/") && strDate.contains(":")) {
            pattern = FORMAT;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        ParsePosition pos = new ParsePosition(0);
        Date startDate = formatter.parse(strDate, pos);
        return startDate;
    }

    /**
     * 将时间格式字符串转换为时间
     *
     * @param strDate
     * @return
     */
    public static Date strToDate(String strDate) {
        return strToDate(strDate, FORMAT);
    }

    /**
     * long 毫秒值转换为Datetime
     *
     * @param date
     * @return Timestamp 用于存入dateTime 格式
     * @addPerson : hzb 2018-3-14
     */
    public Timestamp longToDateTime(long date) {
        return new Timestamp(date);
    }

    /**
     * Date转换为Datetime
     *
     * @param date
     * @return Timestamp 用于存入dateTime 格式
     * @addPerson : hzb 2018-3-14
     */
    public Timestamp dateToDateTime(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * 当前时间生成文件名称，时间(YYYYMMDDMMHHSSSSS)+1位随机数据
     *
     * @return String
     * @author add by gzh
     */
    public static String dateToStringNow() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssss");// 小写的mm表示的是分钟
        String fileName = sdf.format(new Date());
        return fileName;
    }

    public static String dateToStringNow2() {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT);// 小写的mm表示的是分钟
        String fileName = sdf.format(new Date());
        return fileName;
    }

    public static String dateToStringNow2(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);// 小写的mm表示的是分钟
        String fileName = sdf.format(new Date());
        return fileName;
    }

    /**
     * 取当前数据：传入参数据 "year" 取2018
     *
     * @param type "year"，"month","date","hour",minute,
     * @return 2018
     */
    public static int dateNowToDayInt(String type) {
        Calendar c = Calendar.getInstance();// 可以对每个时间域单独修改
        int temp = 0;
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int date = c.get(Calendar.DATE);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        int second = c.get(Calendar.SECOND);
        System.out.println(year + "/" + month + "/" + date + " " + hour + ":" + minute + ":" + second);
        if (type.equals("year")) {
            temp = year;
        } else if (type.equals("month")) {
            temp = month;
        } else if (type.equals("date")) {
            temp = date;
        } else if (type.equals("hour")) {
            temp = hour;
        } else if (type.equals("minute")) {
            temp = minute;
        } else if (type.equals("second")) {
            temp = second;
        }
        return temp;
    }

    /**
     * <li>功能描述：时间相减得到天数
     *
     * @param beginDate
     * @param endDate
     * @return long
     * @author qzm
     */
    public static long getDaySub(Date beginDate, Date endDate) {
        long day = 0;
        try {
            day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            // TODO 自动生成 catch 块
            e.printStackTrace();
        }
        return day;
    }

    public static String getLastDayOfMonth(String dateStr, String pattern) {
        Date d = strToDate(dateStr, pattern);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, Integer.parseInt(formatDate(d, "yyyy")));
        cal.set(Calendar.MONTH, Integer.parseInt(formatDate(d, "MM")) - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        return new SimpleDateFormat(pattern).format(cal.getTime());
    }

    public static String getFirstDayOfMonth(String dateStr, String pattern) {
        Date d = strToDate(dateStr, pattern);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, Integer.parseInt(formatDate(d, "yyyy")));
        cal.set(Calendar.MONTH, Integer.parseInt(formatDate(d, "MM")) - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        return new SimpleDateFormat(pattern).format(cal.getTime());
    }

    public static Date addDays(Date d, int day) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(d);
        rightNow.add(Calendar.DAY_OF_YEAR, day);// 日期加
        Date dt1 = rightNow.getTime();
        return dt1;
    }

    public static Date addMonth(Date d, int month) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(d);
        rightNow.add(Calendar.MONTH, month);// 月份加
        Date dt1 = rightNow.getTime();
        return dt1;
    }

    public static Date addYear(Date d, int year) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(d);
        rightNow.add(Calendar.YEAR, year);// 年份加
        Date dt1 = rightNow.getTime();
        return dt1;
    }

    public static Date addMinutes(Date d, int minutes) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(d);
        rightNow.add(Calendar.MINUTE, minutes);// 月份加
        Date dt1 = rightNow.getTime();
        return dt1;
    }

    //获取当天零点
    public static String getTodayStart() {
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        return todayEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    //获取当天24点
    public static String getTodayEnd() {
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        return todayEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }


    //导出设置默认时间
    public static String getExportStart() {
        LocalDateTime start = LocalDate.now().plusYears(-10).atTime(0, 0, 0);
        return start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    //导出设置默认时间
    public static String getExportEnd() {
        LocalDateTime end = LocalDate.now().plusYears(10).atTime(0, 0, 0);
        return end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * localDateTime to Date
     *
     * @param dateTime
     * @return
     */
    public static Date toDate(LocalDateTime dateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = dateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }


    /**
     * Date  to  localDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * Date  to  localDate
     *
     * @param date
     * @return
     */
    public static LocalDate toLocalDate(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * localDate to Date
     *
     * @param dateTime
     * @return
     */
    public static Date toDate(LocalDate dateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = dateTime.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * 获取当前时间格式化时间
     *
     * @return
     */
    public static String getCurrentTimeFormat() {
        LocalDateTime time = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return dateTimeFormatter.format(time);
    }

    /**
     * 验证查询的时间范围是否有效
     *
     * @return
     */
    public static Date validLimitBookTime(Date bookStartTime, Integer limitDay) {
        // 为空或者 小于0 ，表示不做限制
        if (limitDay == null || limitDay < 0 || limitDay >= 999) {
            return null;
        }
        if (limitDay > 0) {
            limitDay--;
        }
        Date startTime = addDays(new Date(), -limitDay);
        String compStartTime = formatDate(startTime, "yyyy-MM-dd 00:00:00");

        if (bookStartTime == null) {
            // 被限制只能查询的天数，不能为空
            return strToDate(compStartTime, "yyyy-MM-dd 00:00:00");
        }
        String formatBookStartTime = DateUtils.formatDate(bookStartTime, "yyyy-MM-dd HH:mm:ss");
        if (formatBookStartTime.compareTo(compStartTime) < 0) {
            // 限制的日期比查询的日期小，符合，可以进行操作
            return strToDate(compStartTime, "yyyy-MM-dd 00:00:00");
        }
        // 符合不做变更
        return null;
    }

    /**
     * 判断预定救援是否在五分钟之内
     * true:150分钟之内，false:150分钟之外
     * 最新需求：救援预约时间由150分钟，修改为无穷；
     *
     * @param bookTime
     * @return true:及时救援，false:预约救援
     */
    public static boolean checkInTime(Date bookTime) {

        return true;
//        Calendar c1 = Calendar.getInstance();
//        Calendar c3 = Calendar.getInstance();
//        c1.setTime(bookTime);//要判断的日期
//        c3.setTime(new Date());//也给初始日期 把分钟加150
//        c3.add(Calendar.MINUTE, 150);
//        System.out.println("c1" + c1.getTime());
//        System.out.println("c3" + c3.getTime());
//        if (c1.after(c3)) {
//            return false;
//        } else {
//            return true;
//        }
    }

    /**
     * 延迟amount分钟
     *
     * @param amount
     * @return
     */
    public static Date delayDateOfMinute(Integer amount) {
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, amount);
        return nowTime.getTime();
    }

    /**
     * 延迟amount分钟
     *
     * @param amount
     * @return
     */
    public static Date delayDateOfDay(Integer amount) {
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.DATE, amount);
        return nowTime.getTime();
    }

    /**
     * 获取2个时间相隔几分钟,非绝对值
     */
    public static int getMinutesNotAbsolute(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return -1;
        }
        long timeNumber = -1L;
        long TIME = 60L * 1000L;
        try {
            timeNumber = (endDate.getTime() - startDate.getTime()) / TIME;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return (int) timeNumber;
    }

    /**
     * 是否超过24小时
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static boolean isIt24Hours(Date startDate, Date endDate) {
        long cha = startDate.getTime() - endDate.getTime();
        if (cha < 0) {
            return false;
        }
        double result = cha * 1.0 / (1000 * 60 * 60);
        if (result >= 24) {
            return true;
        } else {
            return false;
        }
    }

    public static double it24Hours(Date startDate, Date endDate) {
        long cha = startDate.getTime() - endDate.getTime();
        if (cha < 0) {
            return 0;
        }
        double result = cha * 1.0 / (1000 * 60 * 60);
        return result;
    }

    /**
     * 计算时差(分钟)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static Integer calculateTimeDifferenceByMin(Date d1, Date d2) {
        Integer minutes = null;
        try {
            /*分钟差*/
            long from3 = d1.getTime();
            long to3 = d2.getTime();
            minutes = (int) ((to3 - from3) / (1000 * 60));
            System.out.println("两个时间之间的分钟差为：" + minutes);
        } catch (Exception e) {
            log.error("计算时差错误:{}", e);
        }
        return minutes;
    }


    /**
     * 计算时差(秒)
     *
     * @param d1
     * @return
     */
    public static Long calculateTimeDifferenceBySeconds(Date d1, Date d2) {
        Long seconds = 0L;
        try {
            /*分钟差*/
            long from3 = d1.getTime();
            long to3 = d2.getTime();
            seconds = ((to3 - from3) / 1000);
        } catch (Exception e) {
            log.error("计算时差错误:{}", e);
        }
        return seconds;
    }

    /**
     * 计算时差(秒)
     *
     * @param d1
     * @return
     */
    public static Long calculate24TimeDifferenceBySeconds(Date d1) {
        Long seconds = null;
        try {
            Calendar cal = Calendar.getInstance();
            /*分钟差*/
            long from3 = d1.getTime();
            cal.setTime(d1);
            cal.add(Calendar.HOUR, 24);
            long to3 = cal.getTime().getTime();
            seconds = ((to3 - from3) / 1000);
        } catch (Exception e) {
            log.error("计算时差错误:{}", e);
        }
        return seconds;
    }

    /**
     * 计算时差(小时)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static Integer calculateTimeDifferenceByHour(Date d1, Date d2) {
        Integer hours = null;
        try {
            /*天数差*/
//            long from1 = d1.getTime();
//            long to1 = d2.getTime();
//            int days = (int) ((to1 - from1) / (1000 * 60 * 60 * 24));
//            System.out.println("两个时间之间的天数差为：" + days);

            /*小时差*/
            long from2 = d1.getTime();
            long to2 = d2.getTime();
            hours = (int) ((to2 - from2) / (1000 * 60 * 60));
            System.out.println("两个时间之间的小时差为：" + hours);

            /*分钟差*/
//            long from3 = d1.getTime();
//            long to3 = d2.getTime();
//            int minutes = (int) ((to3 - from3) / (1000 * 60));
//            System.out.println("两个时间之间的分钟差为：" + minutes);
        } catch (Exception e) {
            log.error("计算时差错误:{}", e);
        }
        return hours;
    }

    /**
     * 计算时差(秒)
     *
     * @param warningHappendTime
     * @return
     */
    public static Integer calculateRemainDay(Date warningHappendTime, Integer remain) {
        Integer day = null;
        Calendar cal = Calendar.getInstance();
        cal.setTime(warningHappendTime);
        cal.add(Calendar.DATE, remain);
        long to = cal.getTime().getTime();

        day = (int) ((to - new Date().getTime()) / (1000 * 60 * 60 * 24));
        if (day <= 0) {
            day = 0;
        }
        return day;
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    /**
     * 获取下一个月的日期
     *
     * @param pattern
     * @return
     */
    public static String getNextMonth(String pattern) {
        Date date = new Date();
        //日期加一个月
        Date nextMonth = DateUtils.addMonth(date, 1);
        return DateUtils.formatDate(nextMonth, pattern);
    }

    public static String getNextMonth(Date date, String pattern) {
        //日期加一个月
        Date nextMonth = DateUtils.addMonth(date, 1);
        return DateUtils.formatDate(nextMonth, pattern);
    }

    /**
     * 计算是否为周末 周日或周六
     *
     * @param date 传入的时间
     * @return -1有错误; 0不是周末; 1是周末
     */
    public static int isWeeked(Date date) {
        int result = 0;
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            int week_index = cal.get(Calendar.DAY_OF_WEEK);
            if (week_index == 1 || week_index == 7) {
                result = 1;
            }
        } catch (Exception e) {
            result = -1;
            e.printStackTrace();
        }
        return result;
    }

    public static List<String> getWeekEveryDayString() {
        List<String> dayList = new ArrayList<>();
        Calendar c = Calendar.getInstance();
        // 今天是一周中的第几天
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        if (c.getFirstDayOfWeek() == Calendar.SUNDAY) {
            c.add(Calendar.DAY_OF_MONTH, 1);
        }
        // 计算一周开始的日期
        c.add(Calendar.DAY_OF_MONTH, -dayOfWeek);
        for (int i = 1; i <= 7; i++) {
            c.add(Calendar.DAY_OF_MONTH, 1);
            dayList.add(FORMAT_YYYY_MM_DD.format(c.getTime()));
        }
        return dayList;
    }

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = sdf.parse("2020-07-31 10:20:00");
        boolean b = checkInTime(parse);
        System.out.println(b);
    }
}
